﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Money
{
    // TODO it would be good if we could also have NOT rules for matches

    public class TransactionMatchRule
    {
        private int _priority = 100;

        public int? CategoryId { get; set; }
        public int? CategoryGroupId { get; set; }
        public decimal? MinimumAmount { get; set; }
        public decimal? MaximumAmount { get; set; }
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }
        public string Description { get; set; }
        public string Account { get; set; }
        public bool? IgnoreSign { get; set; }
        public Transaction.TransactionType? Type { get; set; }
        public bool Terminate { get; set; }
        public bool? Edited { get; set; }

        public bool HideIgnored { get; set; }

        public int Priority 
        {
            get
            {
                // HACK we do not want any values of 0 for priority
                if (_priority == 0)
                {
                    _priority = 100;
                }

                return _priority;
            }
            set { _priority = value; } 
        }

        public TransactionMatchRule()
        {
            Terminate = false;

            _priority = 100;

            HideIgnored = false;
        }

        public bool IsMatch(Transaction transaction)
        {
            bool isMatch = true;

            if (CategoryId != null)
            {
                if (CategoryId != transaction.CategoryId)
                {
                    isMatch = false;
                }
            }

            if (CategoryGroupId != null)
            {
                if (CategoryGroupId != transaction.ParentId)
                {
                    isMatch = false;
                }
            }

            if (MaximumAmount != null)
            {
                if (IgnoreSign == true)
                {
                    if (Math.Abs(transaction.Amount) > MaximumAmount)
                    {
                        isMatch = false;
                    }
                }
                else
                {
                    if (transaction.Amount > MaximumAmount)
                    {
                        isMatch = false;
                    }
                }
            }

            if (MinimumAmount != null)
            {
                if (IgnoreSign == true)
                {
                    if (Math.Abs(transaction.Amount) < MinimumAmount)
                    {
                        isMatch = false;
                    }
                }
                else
                {
                    if (transaction.Amount < MinimumAmount)
                    {
                        isMatch = false;
                    }
                }
            }

            if (Type != null)
            {
                if (Type != transaction.Type)
                {
                    isMatch = false;
                }
            }

            if (!string.IsNullOrWhiteSpace(Account))
            {
                if (!Account.Equals(Accounts.AllAccounts, StringComparison.CurrentCultureIgnoreCase))
                {
                    if (!Account.Equals(transaction.Account))
                    {
                        isMatch = false;
                    }
                }
            }

            if (HideIgnored == true)
            {
                if (transaction.CategoryId == Convert.ToInt32(Categories.DefaultCategories.Ignore) || transaction.ParentId == Convert.ToInt32(Categories.DefaultCategories.Ignore))
                {
                    isMatch = false;
                }
            }

            if (StartDate != null)
            {
                if (StartDate.Year > 2000)
                {
                    if (StartDate > transaction.Date)
                    {
                        isMatch = false;
                    }
                }
            }

            if (EndDate != null)
            {
                if (EndDate.Year > 2000)
                {
                    if (EndDate < transaction.Date)
                    {
                        isMatch = false;
                    }
                }
            }

            if (!string.IsNullOrWhiteSpace(Description))
            {
                if (!Regex.IsMatch(transaction.Description, Description, RegexOptions.IgnoreCase))
                {
                    isMatch = false;
                }
            }

            if (Edited != null)
            {
                if (transaction.IsDirty != Edited)
                {
                    isMatch = false;
                }
            }

            return isMatch;
        }
    }
}
